using System.Collections.Generic;
using NaughtyAttributes;
using UnityEngine;

namespace Gj
{
    public class AdaptiveSize : MonoBehaviour
    {
        public enum Type
        {
            Sum,
            Max
        }

        public bool debug;
        public RectTransform Rect;
        public Vector2 offset;
        public Vector2 min;
        public Vector2 max;
        public bool vertical = true;
        public bool horizontal = true;
        public Type verticalType = Type.Sum;
        public Type horizontalType = Type.Sum;
        public AdaptiveSize[] child;
        public AdaptiveSize parent;
        public LocationExtend location;
        public bool auto;
        public bool only;
        public bool data;

        public Vector2 GetSize()
        {
            if (!gameObject.activeSelf) return Vector2.zero;
            var size = data ? GetChildSize() : Vector2.zero;
            return new Vector2(horizontal && data ? size.x : Rect.rect.width,
                vertical && data ? size.y : Rect.rect.height) + offset;
        }

        private Vector2 GetChildSize()
        {
            var size = Vector2.zero;
            for (var i = 0; i < child.Length; i++)
            {
                var _s = child[i].GetSize();
                switch (verticalType)
                {
                    case Type.Sum:
                        size.y += _s.y;
                        break;
                    case Type.Max:
                        size.y = size.y > _s.y ? size.y : _s.y;
                        break;
                }

                switch (horizontalType)
                {
                    case Type.Sum:
                        size.x += _s.x;
                        break;
                    case Type.Max:
                        size.x = size.x > _s.x ? size.x : _s.x;
                        break;
                }
            }
            
            return size;
        }

        public void SetSize(Vector2 v)
        {
            var size = v + offset;
            if (vertical)
            {
                if (size.y > max.y && max.y != 0) size.y = max.y;
                if (size.y < min.y) size.y = min.y;
                Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y);
            }

            if (horizontal)
            {
                if (size.x > max.x && max.x != 0) size.x = max.x;
                if (size.x < min.x) size.x = min.x;
                Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.x);
            }
        }

        [Button]
        public void Refresh()
        {
            if (debug) Debug.LogErrorFormat("Refresh: {0} {1}", gameObject.name, GetSize());
            if (auto)
            {
                var list = new List<AdaptiveSize>();
                for (var i = 0; i < transform.childCount; i++)
                {
                    if (!transform.GetChild(i).gameObject.activeSelf) continue;
                    var item = transform.GetChild(i).GetComponent<AdaptiveSize>();
                    if (item != null) list.Add(item);
                }

                child = list.ToArray();
            }

            if (child.Length != 0)
                if (!data)
                    SetSize(GetChildSize());

            if (parent != null)
            {
                if (only)
                    parent.SetSize(GetSize());
                else
                    parent.Refresh();
            }

            if (location != null) location.Magnet();
        }

        [Button]
        public void ShowSize()
        {
            Debug.Log(GetSize());
            Debug.Log(GetChildSize());
        }
    }
}